package com.hengshan.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hengshan.common.enums.RedisKey;
import com.hengshan.common.utils.JWTUtil;
import com.hengshan.common.utils.RedisUtil;
import com.hengshan.domain.LoginUser;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * token验证处理
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class TokenService {

    private static final int EXPIRE_TIME = 30;

    private final RedisUtil redisUtil;

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public LoginUser getLoginUser(HttpServletRequest request) {
        // 获取请求携带的令牌
        String token = request.getHeader("Authorization");
        if (StringUtils.isNotEmpty(token) && token.startsWith("Bearer ")) {
            token = token.replace("Bearer ", "");
            try {
                Claims claims = JWTUtil.parseJWT(token);
                String userId = claims.getSubject();
                LoginUser loginUser = RedisUtil.get(RedisKey.LOGIN_USER_KEY + userId);
                return loginUser;
            } catch (Exception e) {
                log.error("获取用户信息异常'{}'", e.getMessage());
            }
        }
        return null;
    }

    /**
     * 设置用户身份信息
     */
    public void setLoginUser(LoginUser loginUser) {
        if (Objects.nonNull(loginUser)) {
            refreshToken(loginUser);
        }
    }

    /**
     * 删除用户身份信息
     */
    public void delLoginUser(String token) {
        if (StringUtils.isNotEmpty(token)) {
            Claims claims = JWTUtil.parseJWT(token);
            String userId = claims.getSubject();
            redisUtil.del(RedisKey.LOGIN_USER_KEY + userId);
        }
    }

    /**
     * 验证令牌有效期，相差不足20分钟，自动刷新缓存
     *
     * @param loginUser 登录信息
     */
    public void verifyToken(LoginUser loginUser) {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= 20 * 60 * 1000L) {
            refreshToken(loginUser);
        }
    }

    /**
     * 刷新令牌有效期
     *
     * @param loginUser 登录信息
     */
    public void refreshToken(LoginUser loginUser) {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() +  EXPIRE_TIME * 60 * 1000L);
        redisUtil.set(RedisKey.LOGIN_USER_KEY + loginUser.getUser().getId(), loginUser, EXPIRE_TIME);
    }
}
